package it.polito.let.jhp.form;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class InputAggregator implements Serializable, FormNode {

	private static final long serialVersionUID = -7220525924320667407L;

	private AggregatorType type;

	private List<FormNode> childs;
	
	private InputAggregator parent;

	public InputAggregator (AggregatorType type,InputAggregator parent) {
		this.type = type;
		childs = new ArrayList<FormNode>();
		this.parent = parent;
	}

	public InputAggregator () {
		this(AggregatorType.ALL,null);
	}

	public FormNode add	(FormNode child) {
		childs.add(child);
		return child;
	}

	@Override
	public void checkMandatory(Set<String> fieldSet) throws MandatoryException {
		switch (type) {
		case ALL:
			try {
				for (FormNode n:childs) {
					n.checkMandatory(fieldSet);
				}
			} catch (MandatoryException e) {
				throw new MandatoryException("All of the following fileds are required:\r\n "+toString());
			}
			return;
		case CHOICE:
			int i=0;
			for (FormNode n:childs) {
				try {
					n.checkMandatory(fieldSet);
				} catch (MandatoryException e) {
					i++;
				}
			}
			if (i==childs.size()) {
				throw new MandatoryException("At least  one of the following fileds is required:\r\n "+toString());
			}
			return;
		default:
			/* never reached */
			return;
		}
	}

	public String toString() {
		String result = new String("(");
		boolean first;
		switch (type) {
		case ALL:
			first = true;
			for (FormNode n:childs) {
				if (first) {
					first = false;
				} else {
					result += " AND ";	
				}
				result += n.toString();
			}
			break;
		case CHOICE:
			first = true;
			for (FormNode n:childs) {
				if (first) {
					first = false;
				} else {
					result += " OR ";	
				}
				result += n.toString();
			}
			break;
		}
		result += ")";
		return result;
	}

	@Override
	public void visit() {
		System.err.println(type);
		for (FormNode n:childs)
			n.visit();
	}

	@Override
	public InputAggregator getParent() {
		return parent;
	}
}
